﻿using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Text;



namespace LogException.Library
{
    public class Log
    {


        #region constantes

         private const string _verificaTabelaDeLog = "SELECT ISNULL(name,0) FROM SYSOBJECTS WHERE TYPE='U' AND NAME = @nome;";
        
        #endregion

        #region campos

        private string _stringDeConexao;
        private object _retornoScalar;
        private bool _existeTabelaLog;
        private long _logId;
        private string _nomeTabelaLog;
       
        #endregion


        #region Construtores

        /// <summary>
        /// Construtor que recebe o nome da chave que deve ser utilizada para retornar a string de conexão;
        /// </summary>
        public Log(string ChaveWebConfig,string nomeTabelaLog)
        {
            try
            {
                this._stringDeConexao = System.Web.Configuration.WebConfigurationManager.ConnectionStrings[ChaveWebConfig].ConnectionString;
                this._nomeTabelaLog = nomeTabelaLog;
            }
            catch{}
        }

        /// <summary>
        /// Construtor que usa a chave padrao do web.config ["conexao"];
        /// </summary>
        public Log() 
        {
            try
            {
                this._stringDeConexao = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["conexao"].ConnectionString;
                this._nomeTabelaLog = "tblLogException";
            }
            catch {}
        }

        #endregion



        /// <summary>
        /// Cria um novo registro de log no banco de dados.
        /// </summary>
        public long CriaLog(Exception ex)
        {
            try
            {
                // verifica se existe a string de conexão
                if (String.IsNullOrEmpty(this._stringDeConexao))
                    return -1;  // Não foi possivel encontrar a chave especificada no web.config, para realizar a conexão com o banco de dados;

                // verifica se a tblLog existe no banco de dados. 
                if (!ExisteTabelaDeLog(_nomeTabelaLog))
                    return -2; //Não foi possivel encontrar a tabela de LOG.

                //Insere o Log
                return InsereLog(ex);
            }
            catch { }

            return 0; // Erro interno do processo de log. Não foi possível gravar o Log.
        }

        /// <summary>
        /// Verifica se a tabela de Log esta implementada.Retorna 1 se a tabela esta implementada.
        /// </summary>
        private bool ExisteTabelaDeLog(string NomeDaTabela)
        {
            using (SqlConnection cn = new SqlConnection(_stringDeConexao)) 
            {
                SqlCommand cmd = new SqlCommand(_verificaTabelaDeLog, cn);
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.Add("@nome", SqlDbType.NVarChar).Value = NomeDaTabela;
                cn.Open();
                _retornoScalar = cmd.ExecuteScalar();
                _existeTabelaLog = ((_retornoScalar == null) || _retornoScalar == DBNull.Value) ? false : true;     
            }
                return _existeTabelaLog;
        }

        private long InsereLog(Exception ex) 
        {
            using (SqlConnection cn = new SqlConnection(_stringDeConexao))
            {
                
                StringBuilder _insereLogSQL = new StringBuilder();
                _insereLogSQL.Append("INSERT INTO ");
                _insereLogSQL.Append(_nomeTabelaLog);
                _insereLogSQL.Append(" (innerException, message, source, stackTrace) values(@innerException, @message, @source, @stackTrace); SET @logId = scope_identity();");

                SqlCommand cmd = new SqlCommand(_insereLogSQL.ToString(), cn);
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.Add("@innerException", SqlDbType.NVarChar).Value = "";// ex.InnerException.ToString();
                cmd.Parameters.Add("@message", SqlDbType.NVarChar).Value = ex.Message;
                cmd.Parameters.Add("@source", SqlDbType.NVarChar).Value = ex.Source;
                cmd.Parameters.Add("@stackTrace", SqlDbType.NVarChar).Value = ex.StackTrace;
                cmd.Parameters.Add("@logId", SqlDbType.BigInt).Direction = ParameterDirection.Output;
                cn.Open();
                cmd.ExecuteNonQuery();
                _logId = (long)cmd.Parameters["@logId"].Value;
            }
            return _logId; 
        }
        
    }
}
